package it3807.semOppg1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class DocIndexer {
	
	private String[] directories;
	private String indexPath;
	private Directory indexedDir;
	
	private static Analyzer analyzer = new StandardAnalyzer();

	public static String FIELD_DOC_TEXT = "text";
	public static String FIELD_DOC_NAME = "name";
	public static String FIELD_DOC_PATH = "path";
	public static String FIELD_DOC_ALT = "alt";
	public static String FIELD_DOC_IMGPATH = "imgpath";

	private Pattern imgPattern;
	
	/**
	 * 
	 * @param directories Directories to index
	 * @param indexPath Path where index is stored. 
	 */
	public DocIndexer(String[] directories, String indexPath) {
		this.directories = directories;
		this.indexPath = indexPath;
		
		//imgPattern = Pattern.compile("img src=\"(.*?)\".*?alt=\"(.*?)\"", 
			//	Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ);

		imgPattern = Pattern.compile("alt=\"(.*?)\".*? src=\"(.*?)\"", 
			Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ);

	}
	
	public void generateIndex() throws IOException {
		indexedDir = FSDirectory.getDirectory(indexPath);
		IndexWriter iwriter = new IndexWriter(indexedDir, analyzer, true);
		iwriter.setMaxFieldLength(Integer.MAX_VALUE);
		
		// Read document into index.
		for (String path : directories) {
			
			File[] fileList = listFiles(path);
			if (fileList == null)
				continue; // Ignore on path error.
			
			
			for (File file : fileList) {
				try {
					Logger.info(this, "Indexing file " + file.getName());
					ArrayList<Document> doclist = createDocument(file);
					for (Document doc : doclist) {
						Logger.info(this, "Addign document "
								+ doc.getField(FIELD_DOC_IMGPATH).stringValue()
								+ " to index.");
						iwriter.addDocument(doc);
					}
				}
				catch (FileNotFoundException e) {
					Logger.warn(this, "File " + file.getAbsolutePath() + " not found.");
				}
			}
		}
		
		iwriter.close();
	}

	private ArrayList<Document>  createDocument(File file) throws FileNotFoundException {

		InputStreamReader fh = new InputStreamReader(
					new FileInputStream(file.getPath()));
		
		// les innholdet til streng 
		
		StringBuffer sb = new StringBuffer();
		int buff = 0;
		try {
			for (; buff != -1; buff = fh.read()) {
				sb.append((char) buff);
			}
		} catch (IOException e) {
			Logger.warn(this, "Error reading " + file.getAbsolutePath());
		}
				
		//analyser innhold
		Matcher imgMatcher = imgPattern.matcher(sb.toString());
		
		ArrayList<Document> doclist=new ArrayList<Document>();
		while (imgMatcher.find()) {
			String imgpath = imgMatcher.group(2);
			String alt = imgMatcher.group(1);
			
			Document doc = new Document();
			doc.add(new Field(FIELD_DOC_TEXT, fh));
			doc.add(new Field(FIELD_DOC_NAME, file.getName(),
						Field.Store.YES, Field.Index.TOKENIZED));
			doc.add(new Field(FIELD_DOC_PATH, file.getAbsolutePath(),
					Field.Store.YES, Field.Index.TOKENIZED));
			doc.add(new Field(FIELD_DOC_IMGPATH, imgpath,
					Field.Store.YES, Field.Index.TOKENIZED));
			doc.add(new Field(FIELD_DOC_ALT, alt,
					Field.Store.YES, Field.Index.TOKENIZED));
			//Logger.debug(this, "Created document " + doc.toString());
			
			doclist.add(doc);		
		}
		
		return doclist;
	}

	private File[] listFiles(String path) {
		
		File dirh = new File(path);
		if (!dirh.exists() || !dirh.isDirectory()) {
			Logger.warn(this, "Dir " + path + " does not exist.");
			return null;
		}
		return dirh.listFiles();
	}

	public static Analyzer getAnalyzer() {
		return analyzer;
	}

	public Directory getIndexedDir() {
		return indexedDir;
	}

	public void close() {
		try {
			indexedDir.close();
		} catch (IOException e) {
			Logger.warn(this, "Unable to close indexedDir: " + e.getMessage());
		}
	}
}
